import { Button, Row, Col, Divider, notification, Input, Tag, Modal } from 'antd';
import styles from './style.less';
import { useEffect, useState } from 'react';
import { jsonTextToJsonUsingPOST } from '@/services/ctb-service/json';
import { ProFormRadio } from '@ant-design/pro-form';
import WrapContent from '@/components/WrapContent';

const { TextArea } = Input;
const JsonFormat: React.FC = () => {
  const [visible, setVisible] = useState(1);
  // 左右两边的json字符串
  const [leftJson, setLeftJson] = useState('');
  const [rightJson, setRightJson] = useState('');
  // 代码生成功能的modal可视状态
  const [modalVisible, setModalVisible] = useState(false);

  // 接口入参
  const [params, setParams] = useState({
    language: 'java',
    enableFieldComment: false,
    enableSwaggerAnnotation: false,
    enableLombokAnnotation: false,
  });

  const changeVisibleStyle = (index: number) => {
    setVisible(index);
  };

  const visibleEffectTextSize = () => {
    // 上下视图时，文本框的高度为 12 行，左右视图时，文本框的高度为 24 行
    return visible === 2 ? 12 : 24;
  };

  type NotificationType = 'success' | 'info' | 'warning' | 'error';

  const analyseErrorMessages = (errorMsg: string) => {
    console.log(errorMsg);
    // 正则表达式匹配 line 之后的数字，如果有就拿出第一个数字，没有就返回 null
    const line = errorMsg.match(/line\s+(\d+)/)?.[1];
    // 正则表达式匹配 column 之后的数字，如果有就拿出第一个数字，没有就返回 null
    const column = errorMsg.match(/column\s+(\d+)/)?.[1];
    // 正则表达式匹配 character 之后的字符，如果有就拿出第一个字符，没有就返回 null
    const character = errorMsg.match(/character\s+(\W)/)?.[1];
    return { line, column, character };
  };

  // 提示信息
  const openNotificationWithIcon = (type: NotificationType, description: string, errorMsg: any) => {
    notification.config({
      maxCount: 1,
      duration: 5,
    });
    if (type === 'error' && description === '格式化') {
      const { line, column, character } = analyseErrorMessages(errorMsg);
      const columnUnsure = column === null ? null : Math.min(Number(column) - 3, 0);
      notification[type]({
        message: description + '结果',
        description: (
          <div>
            <p />
            <p>格式化失败！</p>
            <p>
              错误位置：第 {line} 行，第 {columnUnsure} - {column} 列
            </p>
            <p>字符: {character} 附近</p>
          </div>
        ),
      });
      return;
    }
    notification[type]({
      message: description + '结果',
      description: type === 'success' ? '操作成功！' : '操作失败！请检查源数据正确性',
    });
  };

  // 调用接口转换json字符串
  const formatJson = async (methods: number, description: string, extentParam: any) => {
    const res = await jsonTextToJsonUsingPOST({
      textArea: leftJson,
      type: methods,
      ...extentParam,
    });
    if (res.code === 200) {
      setRightJson(res.result);
      openNotificationWithIcon('success', description, null);
    } else {
      openNotificationWithIcon('error', description, res.msg);
    }
  };

  // 交换左右两边的json字符串
  const changeText = () => {
    const temp = leftJson;
    setLeftJson(rightJson);
    setRightJson(temp);
  };

  // 点击按钮弹出modal
  const showModal = () => {
    setModalVisible(true);
  };

  const handleOk = () => {
    formatJson(5, '代码生成', params);
    setModalVisible(false);
  };

  const handleCancel = () => {
    setModalVisible(false);
  };

  useEffect(() => {
    console.log(params);
  }, [params]);

  // 返回一个左右两个框的布局
  return (
    <WrapContent>
      <Row gutter={[16, 16]} justify="space-around" align="middle">
        <Col span={visible === 1 ? 11 : 22}>
          <div className={styles.jsonFormat_old}>
            <Tag className={styles.jsonFormatTag}>原始JSON文本</Tag>
            <div className={styles.jsonFormatButtonGroup}>
              <Button onClick={() => formatJson(0, '随机', params)}>随机</Button>
              <Button onClick={() => formatJson(1, '格式化', params)}>格式化</Button>
              <Button onClick={() => formatJson(2, '压缩', params)}>压缩</Button>
              <Button onClick={() => formatJson(3, '转义', params)}>转义</Button>
              <Button onClick={() => formatJson(4, '反转义', params)}>反转义</Button>
              <Button onClick={() => showModal()}>代码生成</Button>
              <Divider type="vertical" />
              <Button onClick={() => changeVisibleStyle(1)}>左右视图</Button>
              <Button onClick={() => changeVisibleStyle(2)}>上下视图</Button>
              <Button onClick={() => changeText()}>内容交换</Button>
            </div>
            <TextArea
              wrap="off"
              className={styles.jsonFormatTextAreaAround}
              placeholder="请输入JSON文本"
              autoSize={{ minRows: visibleEffectTextSize(), maxRows: visibleEffectTextSize() }}
              allowClear
              showCount
              value={leftJson}
              onChange={(e) => setLeftJson(e.target.value)}
            />
          </div>
        </Col>
        {visible === 1 && (
          <Col span={11}>
            <div className={styles.jsonFormat_new}>
              <Tag className={styles.jsonFormatTagSecond}>转换JSON文本</Tag>
              <div className={styles.jsonFormatTextAreaAround}>
                <TextArea
                  wrap="off"
                  placeholder="转换后的结果将在此展示"
                  autoSize={{ minRows: visibleEffectTextSize(), maxRows: visibleEffectTextSize() }}
                  allowClear
                  showCount
                  value={rightJson}
                  onChange={(e) => setRightJson(e.target.value)}
                />
              </div>
            </div>
          </Col>
        )}
      </Row>
      {visible === 2 && (
        <Row gutter={[16, 16]} justify="space-around" align="middle">
          <Col span={22}>
            <div className={styles.jsonFormat_new}>
              <Tag className={styles.jsonFormatTagSecond}>转换JSON文本</Tag>
              <div className={styles.jsonFormatTextAreaAround}>
                <TextArea
                  wrap="off"
                  placeholder="转换后的结果将在此展示"
                  autoSize={{ minRows: visibleEffectTextSize(), maxRows: visibleEffectTextSize() }}
                  allowClear
                  showCount
                  value={rightJson}
                  onChange={(e) => setRightJson(e.target.value)}
                />
              </div>
            </div>
          </Col>
        </Row>
      )}
      <Modal title="基础选项" open={modalVisible} onOk={handleOk} onCancel={handleCancel}>
        <ProFormRadio.Group
          style={{
            margin: 16,
          }}
          label="代码类型"
          radioType="button"
          fieldProps={{
            value: params.language,
            onChange: (e) => {
              setParams({ ...params, language: e.target.value });
            },
          }}
          options={['java', 'c++', 'js', 'python', 'go']}
        />
        <ProFormRadio.Group
          style={{
            margin: 16,
          }}
          label="生成注释"
          fieldProps={{
            value: params.enableFieldComment,
            onChange: async (e) => {
              await setParams({ ...params, enableFieldComment: e.target.value });
            },
          }}
          options={[
            {
              label: '是',
              value: true,
            },
            {
              label: '否',
              value: false,
            },
          ]}
        />
        <ProFormRadio.Group
          style={{
            margin: 16,
          }}
          label="使用Lombok"
          fieldProps={{
            value: params.enableLombokAnnotation,
            onChange: async (e) => {
              await setParams({ ...params, enableLombokAnnotation: e.target.value });
            },
          }}
          options={[
            {
              label: '是',
              value: true,
            },
            {
              label: '否',
              value: false,
            },
          ]}
        />
        <ProFormRadio.Group
          style={{
            margin: 16,
          }}
          label="使用Swagger"
          fieldProps={{
            value: params.enableSwaggerAnnotation,
            onChange: async (e) => {
              await setParams({ ...params, enableSwaggerAnnotation: e.target.value });
            },
          }}
          options={[
            {
              label: '是',
              value: true,
            },
            {
              label: '否',
              value: false,
            },
          ]}
        />
      </Modal>
    </WrapContent>
  );
};

export default JsonFormat;
